package com.qf.push.server;


import com.alibaba.fastjson.JSONObject;
import com.qf.base.utils.SpringContestUtil;
import com.qf.push.dao.MessageDao;
import com.qf.push.model.Message;
import com.qf.push.model.MessageExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 9090
 */
@ServerEndpoint("/webSocket/{uid}")
@Component
@Slf4j
public class WebSocketServer {



    private MessageDao messageDao;

    /**
     * 每个用户喝服务创建一个会话
     * 我们考虑一个uid对应一个session因此我们
     * 应该维护以uid和session 的关系
     * 所以使用map
     * 又因为这里是连接操作是多线程的并发
     * 因此应该使用线程安全的map
     */

    private static ConcurrentHashMap<String,Session> sessionPool=new ConcurrentHashMap<>();
    /**
     * 当前连接开启的时候的回调方法
     *
     * @param session 代表着这次会话
     * @param uid     代表了当前的用户id
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "uid") String uid) {
        sessionPool.put(uid,session);

        //根据uid查询她的消息 Message 且Message 的state = 0 的所有消息

        //样例对象
        MessageExample example = new MessageExample();
        //条件对象
        MessageExample.Criteria criteria = example.createCriteria();
        //设置uid的条件
        criteria.andUidEqualTo(Long.parseLong(uid));
        //设置state的条件
        criteria.andStateEqualTo(0);
        //按照create_time查询
        example.setOrderByClause("create_time desc");

        if (messageDao == null){
            messageDao = SpringContestUtil.getBean(MessageDao.class);
        }

        //执行查询
        List<Message> messages = messageDao.selectByExample(example);

         //message一次醒推送给前端
        //传输应该用json 而现在是实体类
        //转化List<JSONObject>
        List<JSONObject> msgs = new ArrayList<>();
        for (int i = 0; i < messages.size(); i++) {
            Message message = messages.get(i);
            JSONObject msg = new JSONObject();
            msg.put("serviceId", message.getServiceId());
            msg.put("content", JSONObject.parseObject(message.getContent()));
            msg.put("time", message.getCreateTime());

            msgs.add(msg);
        }

        JSONObject initInfo = new JSONObject();
        initInfo.put("init",true);
        initInfo.put("message",msgs);

        //一次醒给到前端
        sendMessage(session, JSONObject.toJSONString(initInfo));
        //更新数据库，上述所有消息全部推送
        Message msg = new Message();
        msg.setState(1);
        messageDao.updateByExampleSelective(msg, example);

    }

    /**
     * 当对方发送消息时的回调方法
     * @param message 对方发送过来的信息
     */
    @OnMessage
    public void onMessage(String message, @PathParam(value = "uid") String uid) {
        log.info(uid + ":" + message);
    }

    /**
     * 当链接关闭的时候 移除id
     * @param uid 用户的id
     */
    @OnClose
    public void onClose(@PathParam(value="uid") String uid){
        sessionPool.remove(uid);
    }

    /**
     * 当错误发生之时
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("throwable 打印错误 = " + throwable);
        throwable.printStackTrace();
    }

    /**
     * 根据session 发送 message
     */
    private void sendMessage(Session session, String message) {
        if (session != null) {
            synchronized (session) {
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据uid找到session 调用上面方法发送message
     */
    public boolean sendInfo(String uid,String message){
        Session session=sessionPool.get(uid);

        if(session==null){
            return false;
        }
        sendMessage(session,message);
        return true;
    }
}
